const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser'); // 添加对cookies的支持
const fs = require('fs');
const axios = require('axios');  
const jwt = require('jsonwebtoken');  

const app = express();
app.use(cookieParser()); // 添加cookie解析中间件
const port = process.env.PORT || 3000;
// fs读取当前目录下的dist/config.json文件，并将其转成json对象
const configStr = fs.readFileSync(path.join(__dirname, 'dist/config.json'),'utf-8');
const config = JSON.parse(configStr);
// 假设的权限清单URL集合
const allowedRoutes = config.NEED_AUTH_URLS;
// 默认的密钥列表
const defaultTokens = process.env.DEFAULT_TOKENS ? process.env.DEFAULT_TOKENS.split(',') : ['123456'];
// cookies的过期时间7天
const COOKIES_MAX_AGE = process.env.COOKIE_MAX_AGE || 7;
// jwt的过期时间7天
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || 7;
const LOGIN_JS = config.LOGIN_JS;

// 权限校验中间件
const authenticate = (req, res, next) => {
  const requestedRoute = req.path;
  const token = req.cookies.token; // 获取cookies中的token

  if (allowedRoutes.includes(requestedRoute)) { // 检查路由是否在权限清单中
    // 增加jwt校验
    if (defaultTokens.includes(token) || verifyToken(token)) { // 验证token是否在密钥列表中
      next(); // 访问权限通过，继续处理请求
    } else {
      /**
       * 如果requestedRoute以.html结尾，则重定向到登录页
       * 如要requestedRoute以.js结尾，则跳转到login.js页面
       */
      if (requestedRoute.endsWith('.html')) {
        res.redirect('/login.html'); // token不正确，重定向到登录页
      } else if (requestedRoute.endsWith('.js')) {
        res.redirect(LOGIN_JS); // token不正确，跳转到login.js页面
      } else {
        res.status(403).send('Forbidden'); // token不正确，返回403 Forbidden
     }
    }
  } else {
    next(); // 路由不在权限清单中，直接继续处理请求（可能需要修改为403 Forbidden）
  }
};
// 应用权限校验中间件
app.use(authenticate);

// 设置dist目录为静态资源文件夹
app.use(express.static(path.join(__dirname, 'dist')));


// 计算指定天数的毫秒数
function daysToMilliseconds(days) {
  return days * 24 * 60 * 60 * 1000;
}

// 登录路由
app.get('/doLogin', (req, res) => {
  const password = req.query.password;
  if (defaultTokens.includes(password)) {
    res.cookie('token', createToken(JWT_EXPIRES_IN), {
      httpOnly: true, // 防止JavaScript访问
      maxAge: daysToMilliseconds(COOKIES_MAX_AGE), // 设置cookie有效期为7天
    });
    res.redirect('/');
  } else {
    res.redirect('/error.html');
  }
});
const JWT_SECRET = process.env.JWT_SECRET || '123456';  

/**
 * 创建JWT
 * @param {*} expDay 
 * @returns 
 */
const createToken = (expDay = 7) =>{
  // 创建一个JWT的payload部分，它通常包含用户信息  
  const payload = {  
    username: 'mldong',
    sub: '1', // 通常是一个用户ID  
    exp: Math.floor(Date.now() / 1000) + (60 * 60) * 24 * expDay, // 过期时间设置为7天后  
  };  
    
  // 使用JWT库生成一个token  
  const token = jwt.sign(payload, JWT_SECRET); 
  return token;
}
/**
 * 校验JWT
 * @param {*} token 
 * @returns 
 */
const verifyToken = (token) =>{  
  try {  
    jwt.verify(token, JWT_SECRET)
    return true;
  } catch (err) {  
    return false; 
  }  
}  
  
app.get('/giteeCallback', async (req, res) => {
  // 1. 根据授权码获取access_token
  // 2. 检测授权用户是否star仓库
  // 3. 使用jwt生成临时密钥
  try {  
    // 获取码云授权码
    const code = req.query.code;
    // 获取重定向地址
    const redirect_uri = process.env.GITEE_REDIRECT_URI || `http://localhost:${port}${req.path}`;
    const client_id = process.env.GITEE_CLIENT_ID || "0063bdc3a3ddb0c0ab5bc84f8c930300cf786eee8fbaaac6a3bbd22e0e6092cd";
    const client_secret = process.env.GITEE_CLIENT_SECRET || "b4001508ab3f6592a7c5bf50ab83ba2adc6ebdeea4d9da606023c6b219b0e0cd"
    const tokenApiUrl = `https://gitee.com/oauth/token?grant_type=authorization_code&code=${code}&client_id=${client_id}&redirect_uri=${redirect_uri}&client_secret=${client_secret}`;  
    const response = await axios.post(tokenApiUrl);  
    const access_token = response.data.access_token 
    const owner = process.env.GITEE_OWNER || "mldong666";
    const repo = process.env.GITEE_REPO || "mldong-doc-cli";
    const checkUrl = `https://gitee.com/api/v5/user/starred/${owner}/${repo}?access_token=${access_token}`;
    try{
      await axios.get(checkUrl);
      res.cookie('token', createToken(JWT_EXPIRES_IN), {
        httpOnly: true, // 防止JavaScript访问
        maxAge: daysToMilliseconds(COOKIES_MAX_AGE), // 设置cookie有效期为7天
      });
      res.redirect('/');
    } catch(error){
      res.redirect('/error.html?type=2');
    }
  } catch (error) {  
    res.redirect('/error.html?type=3');  
  }  
})

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});